package se.webbzon.boltzmann;

import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;

import se.webbzon.oschi01.collision3d.CollisionCube3D;
import se.webbzon.oschi01.collision3d.CollisionEllipsoid3D;
import se.webbzon.oschi01.worldarea.WorldArea;
import se.webbzon.oschi01.worldarea.WorldEngine;
import se.webbzon.oschi01.worldarea.DefaultWorldEngineTimer;
import se.webbzon.oschi01.worldarea.WorldLiveness;
import se.webbzon.oschi01.worldcamera.AbstractWorldView;
import se.webbzon.oschi01.worldcamera.SimpleWorldRenderer;
import se.webbzon.oschi01.worldcamera.WorldView;
import se.webbzon.oschi01.worldcamera.WorldViewException;
import se.webbzon.oschi01.worldobject.WorldMovableObject;
import se.webbzon.oschi01.worldobject.WorldObject;
import se.webbzon.oschi01.worldobject.WorldStaticGroup;
import se.webbzon.oschi01.worldobject.WorldStaticObject;
import se.webbzon.oschi01.worldobject.appearance.Appearance3D;
import se.webbzon.oschi01.worldobject.appearance.CubeAppearance3D;
import se.webbzon.oschi01.worldobject.appearance.DirectionalLightAppearance3D;
import se.webbzon.oschi01.worldobject.appearance.EllipsoidAppearance3D;
import se.webbzon.oschi01.worldobject.appearance.SimpleAppearance3D;

public class Test {

	public static void main(String[] args) {
		/* Setup the world engine. */
		WorldEngine engine = new WorldEngine();
		WorldLiveness.instance().register(engine);
		DefaultWorldEngineTimer timer = new DefaultWorldEngineTimer(15);
		timer.attachEngine(engine);
		//WorldViewFactory factory = new WorldViewFactory(WorldViewFactory.TRANSPARENCY,engine,timer);
		SimpleWorldRenderer renderer = SimpleWorldRenderer.instance();
		renderer.attachEngine(engine);
		
		JFrame f = new JFrame();
		try {
			AbstractWorldView view = renderer.openWorldView(new Dimension(640,480));
			f.add(view);
			view.getCamera().setProjectionMinDistance(0.1);
			view.getCamera().setProjectionMaxDistance(1000);
			view.getCamera().projectPerspective(new Point3d(0,320,320), new Point3d(), new Vector3d(0,1,0));
		} catch (WorldViewException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		f.pack();
		f.setVisible(true);
		
		WorldArea w = new WorldArea(0);
		C1 c1  = new C1();
		w.createInstance(c1);
		C2 a = new C2(1,3,-0.5/32,Color.blue), b = new C2(32,-96,0.5,Color.red);
		c1.addInstance(a);
		//c1.addInstance(b);
		w.createInstance(a);
		w.createInstance(b);
		w.createInstance(new L());
		engine.setWorld(w);
	}
	
	private static final class C1 extends WorldStaticGroup {

		public C1() {
			super(0, 0, new CubeAppearance3D(0,SimpleAppearance3D.TRANSPARENCY,false));
			setMask(new CollisionCube3D());
			((SimpleAppearance3D)getAppearance()).setTransparency(0.5f);
			setSolid(true);
			setSize(32,32,32);
		}
		
	}
	
	private static final class L extends WorldStaticObject {

		public L() {
			super(0, 0, new DirectionalLightAppearance3D(new Vector3f(1,-2,-3), Color.white));
		}
		
	}
	
	private static final class C2 extends WorldMovableObject {
		
		private final double size;

		public C2(double size, double y, double ay, Color color) {
			super(WorldObject.onStep, 0, new EllipsoidAppearance3D());
			((SimpleAppearance3D)getAppearance()).setColor(color);
			setMask(new CollisionEllipsoid3D());
			setSolid(true);
			this.size = size;
			setSize(size,size,size);
			setPosition(0,y,0);
			setAcceleration(0,ay,0);
		}
		
		public void onStep(WorldArea world) {
			Vector3d p = getTranslation();
			p.set(p.getX(), p.getY() + this.getYVelocity(), p.getZ());
			if (!world.placeFree(this, p, null, null)) {
				world.moveContact(this, getVelocity(), size/2);
				setVelocity(0,- (Math.PI / 4) * getYVelocity(),0);
			}
		}
		
	}

}
